package com.b2b2c.store.sharding.logic;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.b2b2c.store.sharding.service.IBaseService;
import com.b2b2c.until.AbstractPageResult;
import com.b2b2c.until.AjaxPage;
import com.b2b2c.until.Config;
import com.b2b2c.until.PageResultList;
import com.b2b2c.until.PageResultListCovertMap;
import com.b2b2c.until.TimeConvert;

public abstract class AbstractShardingLogic<T> implements IBaseService<T> {

	public HttpServletRequest getReq() {
		return req;
	}

	private HttpServletRequest req;
	
	
	/**
	 * 参数
	 */
	protected Map<String, String> args;

	/**
	 * @param args
	 */
	public  AbstractShardingLogic(Map<String, String> args) {
		this.args = args;
	}

	/**
	 * @param args
	 */
	public AbstractShardingLogic(HttpServletRequest req) {
		this.req = req;
		
	}

	/**
	 * 参数
	 */
	private Map<String, String> param;

	private String splitKey;

	private Object objColum;

	protected String covertsplitKey;

	/**
	 * 数据映射
	 */
	private T objEntityClass;

	// 关联表搜索条件
	protected String associationWhere = "";

	/**
	 * 时间搜索键
	 */
	private String timeGpKey = "timegp";

	/**
	 * 搜索条件临时属性
	 */
	protected String searchTemporary = "";

	public void setAssociationWhere(String associationWhere) {
		this.associationWhere = associationWhere;
	}

	public Object getobjColum() {
		return objColum;
	}


	/**
	 * 分页读取数据
	 * 
	 * @return array
	 */
	public <M> PageResultList<T> getDataByPage(M mapper) {
		int pageNumber = this.getPageNumber();
		
		Map<String, String> requestMap = this.parseRequestParam();
		
		int count = this.count(requestMap);

		AjaxPage pageObj = new AjaxPage(count, pageNumber, requestMap);

		List<T> dataList = this.getDataList(requestMap);


		PageResultList<T> result =  PageResultList.getResult(dataList, pageObj);

		return result;
	}

	//获取总条数
	protected abstract int count(Map<String, String> param);
	
	//处理请求参数
	protected Map<String, String> parseRequestParam() {
		
		Map<String, String> param = new HashMap<String, String>(this.getMap());
		
		int pageNumber = Integer.valueOf(Config.getInstance("system").getSystemConf().get("page_number"));
		
		String storeId = this.getReq().getSession().getAttribute("store_id").toString();
		
		int page = Integer.valueOf(param.get("p"));
		
		param.put("store_id", storeId);
		
		param.put("limit", String.valueOf( pageNumber));
		
		param.put("offset", String.valueOf((page - 1) *  pageNumber));
		
		System.out.println(param);
		
		return param;
		
	}
	
	
	/**
	 * 
	 * @param dataList
	 * @param pageObj
	 * @return
	 */
	protected AbstractPageResult<T> getResult(List<T> dataList, AjaxPage pageObj) {

		PageResultListCovertMap<T> result = PageResultListCovertMap.getResult(dataList, pageObj);

		return result;
	}

	/**
	 * 获取排序
	 */
	protected String getSearchOrderKey() {
		try {
			return ((String) this.objColum.getClass().getMethod("getId").invoke(this.objColum)) + " DESC ";
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * 获取分页数目
	 */
	protected int getPageNumber() {
		return Integer.valueOf((Config.getInstance("system").getConfig().get("page_number")));
	}

	/**
	 * 获取 分页类
	 */
	protected String getPageClass() {
		return Config.getInstance("system").getConfig().get("page_class");
	}

	/**
	 * 组装搜索条件（模糊搜索）
	 * 
	 * @return array
	 */
	protected String getSearchBuildWhere() {
		if (this.param == null) {
			return "";
		}

		String[] likeSearch = this.likeSearchArray();

		if (likeSearch.length == 0) {
			return "";
		}

		Map<String, String> data = this.parseDataWhere();

		Map<String, String> mapSearch = this.create(data);

		if (mapSearch.isEmpty()) {

			return "";
		}

		StringBuilder str = new StringBuilder(" 1=1 ");

		Object value;

		for (int i = 0; i < likeSearch.length; i++) {

			value = mapSearch.get(likeSearch[i]);

			if (value == null) {
				continue;
			}

			str.append(" and ").append(likeSearch[i]).append(" like ").append(value).append("%");
		}

		return str.toString().substring(0, str.length() - 1);
	}

	/**
	 * 组装搜索条件（匹配搜索）
	 * 
	 * @return array
	 */
	protected String getMatchingSearchBuildWhere() {
		if (this.param == null) {
			return "";
		}

		String[] search = this.searchArray();

		if (search.length == 0) {
			return "";
		}

		Map<String, String> mapSearch = this.create(this.param);

		if (mapSearch.isEmpty()) {

			return "";
		}

		StringBuilder str = new StringBuilder(" 1=1 ");

		Object value;

		for (int i = 0; i < search.length; i++) {

			value = mapSearch.get(search[i]);

			if (value == null) {
				continue;
			}

			str.append(" and ").append(search[i]).append(" = ").append(value);
		}

		return str.toString();
	}

	/**
	 * 处理时间 搜索条件
	 * 
	 * @return array
	 */
	protected String parseTimeWhere() {

		String timeParam = this.param.get(this.timeGpKey);

		if (null == timeParam) {
			return "";
		}

		if (-1 == timeParam.indexOf(" - ")) {
			return "";
		}

		String[] time = timeParam.split(" - ");

		TimeConvert timeObj = new TimeConvert(time[0]);

		String startTime = timeObj.dateToStamp();

		timeObj.setTime(time[1]);

		String endTime = timeObj.dateToStamp();

		return " between " + startTime + " and " + endTime;
	}

	/**
	 * 获取模糊搜索字段
	 * 
	 * @return
	 */
	protected String[] likeSearchArray() {
		return new String[0];
	}

	/**
	 * 
	 * @return
	 */
	protected String[] searchArray() {
		return new String[0];
	}

	/**
	 * 获取搜索时间splitKey
	 */
	protected String getSearchTimesplitKey() {
		Class<?> cs = this.objColum.getClass();

		try {
			return (String) cs.getMethod("getCreate_time").invoke(this.objColum);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";
	}

	/**
	 * 回调方法【处理方法】关联字段相互替换
	 */
	protected Map<String, String> parseDataWhere() {
		Map<String, String> map = new HashMap<String, String>(this.param);

		map.put(this.covertsplitKey,
				!map.containsKey(this.splitKey) ? map.get(this.covertsplitKey) : map.get(this.splitKey));

		map.remove(this.splitKey);

		return map;
	}

	/**
	 * 删除不是数据库字段的数据
	 * 
	 * @param param
	 * @return
	 */
	private Map<String, String> create(Map<String, String> data) {
		return null;
	}

	public Map<String, String> getParam() {
		return param;
	}

	public void setParam(Map<String, String> param) {
		this.param = param;
	}

	public String getsplitKey() {
		return splitKey;
	}

	public void setsplitKey(String splitKey) {
		this.splitKey = splitKey;
	}

	public Map<String, String> getMap() {
		// TODO Auto-generated method stub
		Map<String, String> map = new HashMap<String, String>();

		Enumeration<String> param = this.req.getParameterNames();
		while (param.hasMoreElements()) {
			String paramName = param.nextElement();

			String paramValue = this.req.getParameter(paramName);
			// 形成键值对应的map
			map.put(paramName, paramValue);
		}

		return map;
	}
	
	/**
	 * 验证参数规则
	 */
	abstract public Map<String, Map<String, String>> getValidateRule();
}
